#include <unistd.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "wrap.h"
#include <error.h>
#include <fcntl.h>

int main(int argc,char *argv[]){
    int i;
    char ip[INET_ADDRSTRLEN];
    char buf[1024]="";
    int n;
    struct sockaddr_in cliaddr;
    socklen_t len;
    int lfd=tcp4bind(8008,NULL);
    //listen
    Listen(lfd,123);
    //创建树
    int epfd=epoll_create(1);
    //lfd上树
    struct epoll_event ev,evs[1024];
    ev.data.fd=lfd;
    ev.events=EPOLLIN;
    epoll_ctl(epfd,EPOLL_CTL_ADD,lfd,&ev);
    while(1){
        int nready=epoll_wait(epfd,evs,1024,-1);
        if(nready<0){
            perror("epoll_wait error\n");
        }else if(nready==0){
            continue;
        }else{
            for(i=0;i<nready;i++){
                if(evs[i].data.fd==lfd&& evs[i].events&EPOLLIN){
                    len=sizeof(cliaddr);
                    int cfd=Accept(lfd,(struct sockaddr*)&cliaddr,&len);
                    printf("connet client %s is port %d\n",
                            inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,ip,sizeof(ip)),
                            ntohs(cliaddr.sin_port));
                    //非阻塞
                    int flags=fcntl(cfd,F_GETFL);
                    flags|=O_NONBLOCK;
                    fcntl(cfd,F_SETFL,flags);
                    //上树
                    ev.data.fd=cfd;
                    ev.events=EPOLLIN|EPOLLET;
                    epoll_ctl(epfd,EPOLL_CTL_ADD,cfd,&ev);
                }else if(evs[i].events & EPOLLIN){
                    buf[1024]="";
                    n=read(evs[i].data.fd,buf,sizeof(buf));
                    if(n<0){
                        if(error==EAGAIN)   break;
                        perror("read cfd error\n");
                        close(evs[i].data.fd);
                        epoll_ctl(epfd,EPOLL_CTL_DEL,evs[i].data.fd,&evs[i]);
                        break;
                    }else if(0==n){
                        printf("client close\n");
                        close(evs[i].data.fd);
                        epoll_ctl(epfd,EPOLL_CTL_DEL,evs[i].data.fd,&evs[i]);
                        break;
                    }else{
                        write(STDOUT_FILENO,buf,n);
                    } 
                }
            }
        }  
    }
    return 0;
    close(lfd);
}

